﻿using System;
using System.Collections.Concurrent;
using System.ComponentModel.DataAnnotations.Schema;
using Dommel;
using K9Nano.DapperExtensions;
using K9Nano.Domain;
using K9Nano.Share.Annotations;
using K9Nano.Share.Extensions;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class DapperServiceCollectionExtensions
    {
        /// <summary>
        /// 添加Dapper，实现只读仓储。
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="sharedScheme">共享库的名称</param>
        /// <returns></returns>
        public static IK9NanoAppBuilder AddDapper(this IK9NanoAppBuilder builder, string sharedScheme)
        {
            builder.Services.AddScoped(typeof(IReadOnlyRepository<,>), typeof(DapperReadOnlyRepository<,>));
            builder.Services.AddScoped(typeof(IReadOnlyRepository), typeof(DapperReadOnlyRepository));

            DommelMapper.SetTableNameResolver(new CustomTableNameResolver(sharedScheme));

            return builder;
        }
    }


    internal class CustomTableNameResolver : ITableNameResolver
    {
        private readonly string _sharedScheme;

        private readonly ConcurrentDictionary<Type, string> _cache;

        public CustomTableNameResolver(string sharedScheme)
        {
            _sharedScheme = sharedScheme;
            _cache = new ConcurrentDictionary<Type, string>();
        }

        public string ResolveTableName(Type type)
        {
            return _cache.GetOrAdd(type, t =>
            {
                string tableName;
                if (t.TryGetCustomAttribute<TableAttribute>(false, out var table))
                {
                    tableName = table.Name.ToSnakeCase();
                }
                else
                {
                    tableName = type.Name.ToSnakeCase();
                }

                if (t.TryGetCustomAttribute<SharedTableAttribute>(false, out _))
                {
                    return $"{_sharedScheme}.{tableName}";
                }

                return tableName;
            });
        }
    }
}
